import requests
import json
import re
import time
from common.logger import logger
import threading

lock = threading.RLock()

baseAPI = "https://api.haozhuma.com"


class SmsCodeReceive:
    def __init__(self, token, itemid) -> None:
        self.token = token
        self.phone = ""
        self.code = ""
        self.max_wait_time = 60
        self.interval = 1
        self.itemid = itemid

    def build_headers(self):
        headers = {}
        headers["Authorization"] = self.token
        return headers

    def take_phone(self) -> str:
        """
            token	是	string	令牌
            sid	是	int	项目ID
            isp	否	int	运营商，isp=1代表中国移动，参考运营商参数代码表
            Province	否	string	号码省份，Province=44代表广东，参考省份代码表
            ascription	否	int	号码类型，留空为不限制，ascription=1只取虚拟，ascription=2只取实卡
            paragraph	否	int	只取号段，留空为不限制
            exclude	否	int	排除号段，留空为不限制
            uid	否	string	只取该对接码，加入多个对接码时可以用该参数只取这个对接码的手机号
            author	否	string	开发者账号（置入该参数获取消费分成）开发者分成50%
        """
        params = {"sid": self.itemid, "token": self.token}

        with lock:
            rspJson = requests.get(
                baseAPI + "/sms/?api=getPhone",
                params=params,
                headers=self.build_headers(),
            ).json()
            if str(rspJson["code"]) == '0':
                self.phone = rspJson["phone"]
                time.sleep(0.2)
                return self.phone
            else:
                raise Exception(rspJson)

    def get_code(self) -> str:
        """
            requests:
                https://服务器地址/sms/?api=getMessage&token=用户令牌&sid=项目ID&phone=号码
                token	是	string	令牌
                sid	是	int	项目ID
                phone	是	int	号码
            response:
                code	状态码，code=0，code=其他为失败
                msg	描述
                sms	完整短信内容
                yzm	系统识别的数字验证码
        """
        if not self.phone:
            raise Exception("phone is empty")

        try:
            start_time = time.time()

            while True:
                if time.time() - start_time > self.max_wait_time:
                    raise Exception(f"验证码获取超时:{self.phone}")

                json_data = {
                    "token": self.token,
                    "sid": self.itemid,
                    "phone": self.phone,
                }

                rsp = requests.get(
                    baseAPI + "/sms/?api=getMessage",
                    params=json_data,
                    headers=self.build_headers(),
                )

                try:
                    rspJson = rsp.json()
                except:
                    logger.error(f"获取验证码失败:{rsp.text}")
                    continue

                if str(rspJson["code"]) == '0':
                    self.code = rspJson["yzm"]
                    break

                time.sleep(2)
        finally:
            self.release()

        return self.code

    def add_black(self):
        """
        https://服务器地址/sms/?api=addBlacklist&token=用户令牌&sid=项目ID&phone=号码
        """
        
        url = baseAPI + "/sms/?api=addBlacklist"

        # {"itemlist":[{"itemid":29601,"phone":"16521076072"}],"remark":"去重"}

        params = {
            "sid": self.itemid,
            "phone": self.phone,
            "token": self.token,
        }

        rsp = requests.get(url, params=params, headers=self.build_headers())

        rspJson = rsp.json()

        if str(rspJson["code"]) != '0' and str(rspJson["code"]) != '200':
            logger.warning(f"添加黑名单失败:{rspJson}")
        else:
            logger.debug(f"添加黑名单成功:{rspJson}")

    def release(self):
        """_summary_
            requests:
                https://服务器地址/sms/?api=cancelRecv&token=用户令牌&sid=项目ID&phone=号码
                token	是	string	令牌
                sid	是	int	项目ID
                phone	是	int	号码
            response:
                code	状态码，code=0为成功，code=-1为失败
                data	-
                msg	描述
        """
        
        params = {
            "token": self.token,
            "phone": self.phone,
            "sid": self.itemid,
        }
        
        rsp = requests.get(
            baseAPI + "/sms/?api=cancelRecv",
            params=params,
            headers=self.build_headers(),
        )
        
        rspJson = rsp.json()
        
        if str(rspJson["code"]) != '0' and str(rspJson["code"]) != '200':
            logger.warning(f"释放号码失败:{rspJson}")
        else:
            logger.debug(f"释放号码成功:{rspJson}")
